package test;

import java.util.concurrent.CountDownLatch;

public class MemoryBarrierDemo {

    private static final int THREAD_NUM = 2;
    private static final int LOOP_COUNT = 100000000;

    // 定义共享变量
    // 使用 volatile 关键字来确保变量的可见性和顺序性
    private static volatile long sharedCounter = 0;

    // 定义 CountDownLatch，用于线程同步
    private static CountDownLatch latch = new CountDownLatch(THREAD_NUM);

    public static void main(String[] args) throws InterruptedException {
        long startTime = System.nanoTime();
        // 创建两个线程，对共享变量进行递增操作
        Thread t1 = new Thread(new MyRunnable());
        Thread t2 = new Thread(new MyRunnable());

        // 启动线程
        t1.start();
        t2.start();

        // 等待两个线程执行完毕
        latch.await();

        long endTime = System.nanoTime();
        System.out.println("Time taken: " + (endTime - startTime) + " ns");
        // 输出共享变量的值
        System.out.println("sharedCounter = " + sharedCounter);
    }

    static class MyRunnable implements Runnable {

        @Override
        public void run() {

            // 循环递增共享变量的值
            for (int i = 0; i < LOOP_COUNT; i++) {

                // 内存屏障，确保对于共享变量的读写操作的执行顺序满足特定要求
                // 在本例中，写屏障保证了写操作的可见性
                // 读屏障确保读操作的顺序正确
                // 避免出现数据不一致的情况
                // 可以使用 writeBarrier() 或 release() 等函数实现
                // 这里使用 release() 函数实现
                // 写屏障
                sharedCounter++;

                // 内存屏障，确保对于共享变量的读写操作的执行顺序满足特定要求
                // 在本例中，写屏障保证了写操作的可见性
                // 读屏障确保读操作的顺序正确
                // 避免出现数据不一致的情况
                // 可以使用 readBarrier() 或 acquire() 等函数实现
                // 这里使用 acquire() 函数实现
                // 读屏障
                sharedCounter += 0;

            }

            // 释放 CountDownLatch
            latch.countDown();
        }
    }
}
